home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i066: Jove, an emacs variant, version 4.9, Part10/21
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
- Posting-number: Volume 14, Issue 66
- Archive-name: jove4.9/part10
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 10 (of 21)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './extend.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./extend.c'\"
- else
- echo shar: Extracting \"'./extend.c'\" \(19914 characters\)
- sed "s/^X//" >'./extend.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X#include "jove.h"
- X#include "io.h"
- X#include "termcap.h"
- X#include "ctype.h"
- X#ifdef JOB_CONTROL
- X# include <signal.h>
- X#endif
- X
- X#ifdef MAC
- X# include "mac.h"
- X#else
- X# include <varargs.h>
- X#endif
- X
- X#ifdef MSDOS
- X#include <process.h>
- X#endif
- X
- X#ifdef MAC
- X# undef private
- X# define private
- X#endif
- X
- X#ifdef LINT_ARGS
- private void
- X fb_aux(data_obj *, data_obj **, char *, char *),
- X find_binds(data_obj *, char *),
- X vpr_aux(struct variable *, char *);
- X#else
- private void
- X fb_aux(),
- X find_binds(),
- X vpr_aux();
- X#endif /* LINT_ARGS */
- X
- X#ifdef MAC
- X# undef private
- X# define private static
- X#endif
- X
- X
- int InJoverc = 0;
- X
- extern int getch(),
- X getchar();
- X
- X/* Auto execute code */
- X
- X#define NEXECS 20
- X
- private struct {
- X char *a_pattern;
- X data_obj *a_cmd;
- X} AutoExecs[NEXECS] = {0};
- X
- private int ExecIndex = 0;
- X
- X/* Command auto-execute. */
- X
- void
- CAutoExec()
- X{
- X DefAutoExec(findcom);
- X}
- X
- X/* Macro auto-execute. */
- X
- void
- MAutoExec()
- X{
- X DefAutoExec(findmac);
- X}
- X
- X/* VARARGS0 */
- X
- void
- DefAutoExec(proc)
- X#ifdef LINT_ARGS
- data_obj *(*proc)();
- X#else
- data_obj *(*proc)();
- X#endif
- X{
- X data_obj *d;
- X char *pattern;
- X int i;
- X
- X if (ExecIndex >= NEXECS)
- X complain("Too many auto-executes, max %d.", NEXECS);
- X if ((d = (*proc)(ProcFmt)) == 0)
- X return;
- X pattern = do_ask("\r\n", (int (*)()) 0, (char *) 0, ": %f %s ", d->Name);
- X if (pattern != 0)
- X for (i = 0; i < ExecIndex; i++)
- X if ((AutoExecs[i].a_cmd == d) &&
- X (strcmp(pattern, AutoExecs[i].a_pattern) == 0))
- X return; /* eliminate duplicates */
- X AutoExecs[ExecIndex].a_pattern = copystr(pattern);
- X AutoExecs[ExecIndex].a_cmd = d;
- X ExecIndex += 1;
- X}
- X
- X/* DoAutoExec: NEW and OLD are file names, and if NEW and OLD aren't the
- X same kind of file (i.e., match the same pattern) or OLD is 0 and it
- X matches, OR if the pattern is 0 (none was specified) then, we execute
- X the command associated with that kind of file. */
- X
- void
- DoAutoExec(new, old)
- register char *new,
- X *old;
- X{
- X register int i;
- X
- X set_arg_value(1);
- X for (i = 0; i < ExecIndex; i++)
- X if ((AutoExecs[i].a_pattern == 0) ||
- X ((new != 0 && LookingAt(AutoExecs[i].a_pattern, new, 0)) &&
- X (old == 0 || !LookingAt(AutoExecs[i].a_pattern, old, 0))))
- X ExecCmd(AutoExecs[i].a_cmd);
- X}
- X
- void
- BindAKey()
- X{
- X BindSomething(findcom);
- X}
- X
- void
- BindMac()
- X{
- X BindSomething(findmac);
- X}
- X
- extern void EscPrefix(),
- X CtlxPrefix(),
- X MiscPrefix();
- X
- data_obj **
- IsPrefix(cp)
- data_obj *cp;
- X{
- X#ifdef MAC
- X void (*proc)();
- X#else
- X int (*proc)();
- X#endif
- X
- X if (cp == 0 || (cp->Type & TYPEMASK) != FUNCTION)
- X return 0;
- X proc = ((struct cmd *) cp)->c_proc;
- X if (proc == EscPrefix)
- X return pref1map;
- X if (proc == CtlxPrefix)
- X return pref2map;
- X if (proc == MiscPrefix)
- X return miscmap;
- X return 0;
- X}
- X
- void
- UnbindC()
- X{
- X char *keys;
- X data_obj **map = mainmap;
- X
- X keys = ask((char *) 0, ProcFmt);
- X for (;;) {
- X if (keys[1] == '\0')
- X break;
- X if ((map = IsPrefix(map[*keys])) == 0)
- X break;
- X keys += 1;
- X }
- X if (keys[1] != 0)
- X complain("That's not a legitimate key sequence.");
- X map[keys[0]] = 0;
- X}
- X
- int
- addgetc()
- X{
- X int c;
- X
- X if (!InJoverc) {
- X Asking = strlen(mesgbuf);
- X c = getch();
- X Asking = 0;
- X add_mess("%p ", c);
- X } else {
- X c = getch();
- X if (c == '\n')
- X return EOF; /* this isn't part of the sequence */
- X else if (c == '\\') {
- X if ((c = getch()) == LF)
- X complain("[Premature end of line]");
- X } else if (c == '^') {
- X if ((c = getch()) == '?')
- X c = RUBOUT;
- X else if (isalpha(c) || index("@[\\]^_", c))
- X c = CTL(c);
- X else
- X complain("[Unknown control character]");
- X }
- X }
- X return c;
- X}
- X
- void
- BindWMap(map, lastkey, cmd)
- data_obj **map,
- X *cmd;
- X{
- X data_obj **nextmap;
- X int c;
- X
- X c = addgetc();
- X if (c == EOF) {
- X if (lastkey == EOF)
- X complain("[Empty key sequence]");
- X complain("[Premature end of key sequence]");
- X } else {
- X if (nextmap = IsPrefix(map[c]))
- X BindWMap(nextmap, c, cmd);
- X else {
- X map[c] = cmd;
- X#ifdef MAC
- X ((struct cmd *) cmd)->c_key = c; /* see about_j() in mac.c */
- X if(map == mainmap) ((struct cmd *) cmd)->c_map = F_MAINMAP;
- X else if(map == pref1map) ((struct cmd *) cmd)->c_map = F_PREF1MAP;
- X else if(map == pref2map) ((struct cmd *) cmd)->c_map = F_PREF2MAP;
- X#endif
- X }
- X }
- X}
- X
- X/* VARARGS0 */
- X
- void
- BindSomething(proc)
- X#ifdef LINT_ARGS
- data_obj *(*proc)();
- X#else
- data_obj *(*proc)();
- X#endif
- X{
- X data_obj *d;
- X
- X if ((d = (*proc)(ProcFmt)) == 0)
- X return;
- X s_mess(": %f %s ", d->Name);
- X BindWMap(mainmap, EOF, d);
- X}
- X
- X/* Describe key */
- X
- void
- DescWMap(map, key)
- data_obj **map;
- X{
- X data_obj *cp = map[key],
- X **prefp;
- X
- X if (cp == 0)
- X add_mess("is unbound.");
- X else if (prefp = IsPrefix(cp))
- X DescWMap(prefp, addgetc());
- X else
- X add_mess("is bound to %s.", cp->Name);
- X}
- X
- void
- KeyDesc()
- X{
- X s_mess(ProcFmt);
- X DescWMap(mainmap, addgetc());
- X}
- X
- void
- DescCom()
- X{
- X data_obj *dp;
- X char pattern[100],
- X doc_type[40],
- X *file = CmdDb;
- X File *fp;
- X
- X if (!strcmp(LastCmd->Name, "describe-variable"))
- X dp = (data_obj *) findvar(ProcFmt);
- X else
- X dp = (data_obj *) findcom(ProcFmt);
- X if (dp == 0)
- X return;
- X fp = open_file(file, iobuff, F_READ, COMPLAIN, QUIET);
- X Placur(ILI, 0);
- X flusho();
- X sprintf(pattern, "^:entry \"%s\" \"\\([^\"]*\\)\"", dp->Name);
- X TOstart("Help", TRUE);
- X for (;;) {
- X if (f_gets(fp, genbuf, LBSIZE) == EOF) {
- X Typeout("There is no documentation for \"%s\".", dp->Name);
- X goto outahere;
- X }
- X if ((strncmp(genbuf, ":entry", 6) == 0) && LookingAt(pattern, genbuf, 0))
- X break;
- X }
- X /* found it ... let's print it */
- X putmatch(1, doc_type, sizeof doc_type);
- X if (strcmp("Variable", doc_type) == 0)
- X Typeout(dp->Name);
- X else if (strcmp("Command", doc_type) == 0) {
- X char binding[128];
- X
- X find_binds(dp, binding);
- X if (blnkp(binding))
- X Typeout("To invoke %s, type \"ESC X %s<cr>\".",
- X dp->Name,
- X dp->Name);
- X else
- X Typeout("Type \"%s\" to invoke %s.", binding, dp->Name);
- X }
- X Typeout("");
- X while (f_gets(fp, genbuf, LBSIZE) != EOF)
- X if (strncmp(genbuf, ":entry", 6) == 0)
- X goto outahere;
- X else
- X Typeout("%s", genbuf);
- outahere:
- X f_close(fp);
- X TOstop();
- X}
- X
- void
- DescBindings()
- X{
- X extern void Typeout();
- X
- X TOstart("Key Bindings", TRUE);
- X DescMap(mainmap, NullStr);
- X TOstop();
- X}
- X
- extern int specialmap;
- X
- void
- DescMap(map, pref)
- data_obj **map;
- char *pref;
- X{
- X int c1,
- X c2 = 0,
- X numbetween;
- X char keydescbuf[40];
- X data_obj **prefp;
- X
- X#ifdef IBMPC
- X specialmap = (map == miscmap);
- X#endif
- X
- X for (c1 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
- X c2 = c1;
- X if (map[c1] == 0)
- X continue;
- X while (++c2 < NCHARS && map[c1] == map[c2])
- X ;
- X c2 -= 1;
- X numbetween = c2 - c1;
- X if (numbetween == 1)
- X sprintf(keydescbuf, "%s {%p,%p}", pref, c1, c2);
- X else if (numbetween == 0)
- X sprintf(keydescbuf, "%s %p", pref, c1);
- X else
- X sprintf(keydescbuf, "%s [%p-%p]", pref, c1, c2);
- X if ((prefp = IsPrefix(map[c1])) && (prefp != map))
- X DescMap(prefp, keydescbuf);
- X else
- X Typeout("%-18s%s", keydescbuf, map[c1]->Name);
- X }
- X}
- X
- private void
- find_binds(dp, buf)
- data_obj *dp;
- char *buf;
- X{
- X char *endp;
- X
- X buf[0] = '\0';
- X fb_aux(dp, mainmap, (char *) 0, buf);
- X endp = buf + strlen(buf) - 2;
- X if ((endp > buf) && (strcmp(endp, ", ") == 0))
- X *endp = '\0';
- X}
- X
- private void
- fb_aux(cp, map, prefix, buf)
- register data_obj *cp,
- X **map;
- char *buf,
- X *prefix;
- X{
- X int c1,
- X c2;
- X char *bufp = buf + strlen(buf),
- X prefbuf[20];
- X data_obj **prefp;
- X
- X#ifdef IBMPC
- X specialmap = (map == miscmap);
- X#endif
- X
- X for (c1 = c2 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
- X c2 = c1;
- X if (map[c1] == cp) {
- X while (++c2 < NCHARS && map[c1] == map[c2])
- X ;
- X c2 -= 1;
- X if (prefix)
- X sprintf(bufp, "%s ", prefix);
- X bufp += strlen(bufp);
- X switch (c2 - c1) {
- X case 0:
- X sprintf(bufp, "%p, ", c1);
- X break;
- X
- X case 1:
- X sprintf(bufp, "{%p,%p}, ", c1, c2);
- X break;
- X
- X default:
- X sprintf(bufp, "[%p-%p], ", c1, c2);
- X break;
- X }
- X }
- X if ((prefp = IsPrefix(map[c1])) && (prefp != map)) {
- X sprintf(prefbuf, "%p", c1);
- X fb_aux(cp, prefp, prefbuf, bufp);
- X }
- X bufp += strlen(bufp);
- X }
- X}
- X
- void
- Apropos()
- X{
- X register struct cmd *cp;
- X register struct macro *m;
- X register struct variable *v;
- X char *ans;
- X int anyfs = NO,
- X anyvs = NO,
- X anyms = NO;
- X char buf[256];
- X
- X ans = ask((char *) 0, ": %f (keyword) ");
- X TOstart("Help", TRUE);
- X for (cp = commands; cp->Name != 0; cp++)
- X if (sindex(ans, cp->Name)) {
- X if (anyfs == 0) {
- X Typeout("Commands");
- X Typeout("--------");
- X }
- X find_binds((data_obj *) cp, buf);
- X if (buf[0])
- X Typeout(": %-35s(%s)", cp->Name, buf);
- X else
- X Typeout(": %s", cp->Name);
- X anyfs = YES;
- X }
- X if (anyfs)
- X Typeout(NullStr);
- X for (v = variables; v->Name != 0; v++)
- X if (sindex(ans, v->Name)) {
- X if (anyvs == 0) {
- X Typeout("Variables");
- X Typeout("---------");
- X }
- X anyvs = YES;
- X vpr_aux(v, buf);
- X Typeout(": set %-26s%s", v->Name, buf);
- X }
- X if (anyvs)
- X Typeout(NullStr);
- X for (m = macros; m != 0; m = m->m_nextm)
- X if (sindex(ans, m->Name)) {
- X if (anyms == 0) {
- X Typeout("Macros");
- X Typeout("------");
- X }
- X anyms = YES;
- X find_binds((data_obj *) m, buf);
- X if (buf[0])
- X Typeout(": %-35s(%s)", m->Name, buf);
- X else
- X Typeout(": %-35s%s", "execute-macro", m->Name);
- X }
- X TOstop();
- X}
- X
- void
- Extend()
- X{
- X data_obj *d;
- X
- X if (d = findcom(": "))
- X ExecCmd(d);
- X}
- X
- X/* Read a positive integer from CP. It must be in base BASE, and
- X complains if it isn't. If allints is nonzero, all the characters
- X in the string must be integers or we return -1; otherwise we stop
- X reading at the first nondigit. */
- X
- int
- chr_to_int(cp, base, allints, result)
- register char *cp;
- register int *result;
- X{
- X register int c;
- X int value = 0,
- X sign;
- X
- X if ((c = *cp) == '-') {
- X sign = -1;
- X cp += 1;
- X } else
- X sign = 1;
- X while (c = *cp++) {
- X if (!isdigit(c)) {
- X if (allints == YES)
- X return INT_BAD;
- X break;
- X }
- X c = c - '0';
- X if (c >= base)
- X complain("You must specify in base %d.", base);
- X value = value * base + c;
- X }
- X *result = value * sign;
- X return INT_OKAY;
- X}
- X
- int
- ask_int(prompt, base)
- char *prompt;
- int base;
- X{
- X char *val = ask((char *) 0, prompt);
- X int value;
- X
- X if (chr_to_int(val, base, YES, &value) == INT_BAD)
- X complain("That's not a number!");
- X return value;
- X}
- X
- private void
- vpr_aux(vp, buf)
- register struct variable *vp;
- char *buf;
- X{
- X switch (vp->v_flags & V_TYPEMASK) {
- X case V_BASE10:
- X sprintf(buf, "%d", *(vp->v_value));
- X break;
- X
- X case V_BASE8:
- X sprintf(buf, "%o", *(vp->v_value));
- X break;
- X
- X case V_BOOL:
- X sprintf(buf, (*(vp->v_value)) ? "on" : "off");
- X break;
- X
- X case V_STRING:
- X case V_FILENAME:
- X sprintf(buf, "%s", (char *) vp->v_value);
- X break;
- X
- X case V_CHAR:
- X sprintf(buf, "%p", *(vp->v_value));
- X break;
- X }
- X}
- X
- void
- PrVar()
- X{
- X struct variable *vp;
- X char prbuf[256];
- X
- X if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
- X return;
- X vpr_aux(vp, prbuf);
- X s_mess(": %f %s => %s", vp->Name, prbuf);
- X}
- X
- void
- SetVar()
- X{
- X struct variable *vp;
- X char *prompt;
- X
- X if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
- X return;
- X prompt = sprint(": %f %s ", vp->Name);
- X
- X switch (vp->v_flags & V_TYPEMASK) {
- X case V_BASE10:
- X case V_BASE8:
- X {
- X int value;
- X
- X value = ask_int(prompt, ((vp->v_flags & V_TYPEMASK) == V_BASE10)
- X ? 10 : 8);
- X *(vp->v_value) = value;
- X break;
- X }
- X
- X case V_BOOL:
- X {
- X char *def = *(vp->v_value) ? "off" : "on",
- X *on_off;
- X int value;
- X
- X on_off = ask(def, prompt);
- X if (casecmp(on_off, "on") == 0)
- X value = ON;
- X else if (casecmp(on_off, "off") == 0)
- X value = OFF;
- X else
- X complain("Boolean variables must be ON or OFF.");
- X *(vp->v_value) = value;
- X#ifdef MAC
- X MarkVar(vp,-1,0); /* mark the menu item */
- X#endif
- X s_mess("%s%s", prompt, value ? "on" : "off");
- X break;
- X }
- X
- X case V_FILENAME:
- X {
- X char fbuf[FILESIZE];
- X
- X sprintf(&prompt[strlen(prompt)], "(default %s) ", vp->v_value);
- X (void) ask_file(prompt, (char *) vp->v_value, fbuf);
- X strcpy((char *) vp->v_value, fbuf);
- X break;
- X }
- X
- X case V_STRING:
- X {
- X char *str;
- X
- X /* Do_ask() so you can set string to "" if you so desire. */
- X str = do_ask("\r\n", (int (*)()) 0, (char *) vp->v_value, prompt);
- X if (str == 0)
- X str = NullStr;
- X strcpy((char *) vp->v_value, str);
- X /* ... and hope there is enough room. */
- X break;
- X }
- X case V_CHAR:
- X f_mess(prompt);
- X *(vp->v_value) = addgetc();
- X break;
- X
- X }
- X if (vp->v_flags & V_MODELINE)
- X UpdModLine = YES;
- X if (vp->v_flags & V_CLRSCREEN) {
- X#ifdef IBMPC
- X setcolor(Fgcolor, Bgcolor);
- X#endif /* IBMPC */
- X ClAndRedraw();
- X }
- X if (vp->v_flags & V_TTY_RESET)
- X tty_reset();
- X}
- X
- X/* Command completion - possible is an array of strings, prompt is
- X the prompt to use, and flags are ... well read jove.h.
- X
- X If flags are RET_STATE, and the user hits <return> what they typed
- X so far is in the Minibuf string. */
- X
- private char **Possible;
- private int comp_value,
- X comp_flags;
- X
- int
- aux_complete(c)
- X{
- X int command,
- X length,
- X i;
- X
- X if (comp_flags & CASEIND) {
- X char *lp;
- X
- X for (lp = linebuf; *lp != '\0'; lp++)
- X#if (defined(IBMPC) || defined(MAC))
- X lower(lp);
- X#else
- X if (isupper(*lp))
- X *lp = tolower(*lp);
- X#endif
- X }
- X switch (c) {
- X case EOF:
- X comp_value = -1;
- X return 0;
- X
- X case '\r':
- X case '\n':
- X command = match(Possible, linebuf);
- X if (command >= 0) {
- X comp_value = command;
- X return 0; /* tells ask to stop */
- X }
- X if (eolp() && bolp()) {
- X comp_value = NULLSTRING;
- X return 0;
- X }
- X if (comp_flags & RET_STATE) {
- X comp_value = command;
- X return 0;
- X }
- X if (InJoverc)
- X complain("[\"%s\" unknown]", linebuf);
- X rbell();
- X break;
- X
- X case '\t':
- X case ' ':
- X {
- X int minmatch = 1000,
- X maxmatch = 0,
- X numfound = 0,
- X lastmatch = -1,
- X length = strlen(linebuf);
- X
- X for (i = 0; Possible[i] != 0; i++) {
- X int this_len;
- X
- X this_len = numcomp(Possible[i], linebuf);
- X maxmatch = max(maxmatch, this_len);
- X if (this_len >= length) {
- X if (numfound)
- X minmatch = min(minmatch, numcomp(Possible[lastmatch], Possible[i]));
- X else
- X minmatch = strlen(Possible[i]);
- X numfound += 1;
- X lastmatch = i;
- X if (strcmp(linebuf, Possible[i]) == 0)
- X break;
- X }
- X }
- X
- X if (numfound == 0) {
- X rbell();
- X if (InJoverc)
- X complain("[\"%s\" unknown]", linebuf);
- X /* If we're not in the .joverc then
- X let's do something helpful for the
- X user. */
- X if (maxmatch < length) {
- X char *cp;
- X
- X cp = linebuf + maxmatch;
- X *cp = 0;
- X Eol();
- X }
- X break;
- X }
- X if (c != '\t' && numfound == 1) {
- X comp_value = lastmatch;
- X return 0;
- X }
- X null_ncpy(linebuf, Possible[lastmatch], minmatch);
- X Eol();
- X if (minmatch == length) /* No difference */
- X rbell();
- X break;
- X }
- X
- X case '?':
- X if (InJoverc)
- X complain((char *) 0);
- X /* kludge: in case we're using UseBuffers, in which case
- X linebuf gets written all over */
- X strcpy(Minibuf, linebuf);
- X length = strlen(Minibuf);
- X TOstart("Completion", TRUE); /* for now ... */
- X for (i = 0; Possible[i]; i++)
- X if (numcomp(Possible[i], Minibuf) >= length) {
- X Typeout(Possible[i]);
- X if (TOabort != 0)
- X break;
- X }
- X
- X TOstop();
- X break;
- X }
- X return !FALSE;
- X}
- X
- int
- complete(possible, prompt, flags)
- register char *possible[];
- char *prompt;
- X{
- X Possible = possible;
- X comp_flags = flags;
- X (void) do_ask("\r\n \t?", aux_complete, NullStr, prompt);
- X return comp_value;
- X}
- X
- int
- match(choices, what)
- register char **choices,
- X *what;
- X{
- X register int len;
- X int i,
- X found = 0,
- X save,
- X exactmatch = -1;
- X
- X len = strlen(what);
- X if (len == 0)
- X return NULLSTRING;
- X for (i = 0; choices[i]; i++) {
- X if (strncmp(what, choices[i], len) == 0) {
- X if (strcmp(what, choices[i]) == 0)
- X exactmatch = i;
- X save = i;
- X found += 1; /* found one */
- X }
- X }
- X
- X if (found == 0)
- X save = ORIGINAL;
- X else if (found > 1) {
- X if (exactmatch != -1)
- X save = exactmatch;
- X else
- X save = AMBIGUOUS;
- X }
- X
- X return save;
- X}
- X
- void
- Source()
- X{
- X char *com, *getenv(),
- X buf[FILESIZE];
- X
- X#ifndef MSDOS
- X sprintf(buf, "%s/.joverc", getenv("HOME"));
- X#else /* MSDOS */
- X if (com = getenv("JOVERC"))
- X strcpy(buf, com);
- X else
- X strcpy(buf, Joverc);
- X#endif /* MSDOS */
- X com = ask_file((char *) 0, buf, buf);
- X if (joverc(buf) == 0)
- X complain(IOerr("read", com));
- X}
- X
- void
- BufPos()
- X{
- X register Line *lp = curbuf->b_first;
- X register int i,
- X dotline;
- X long dotchar,
- X nchars;
- X
- X for (i = nchars = 0; lp != 0; i++, lp = lp->l_next) {
- X if (lp == curline) {
- X dotchar = nchars + curchar;
- X dotline = i + 1;
- X }
- X nchars += length(lp) + (lp->l_next != 0); /* include the NL */
- X }
- X
- X s_mess("[\"%s\" line %d/%d, char %D/%D (%d%%), cursor = %d/%d]",
- X filename(curbuf), dotline, i, dotchar, nchars,
- X (nchars == 0) ? 100 : (int) (((long) dotchar * 100) / nchars),
- X calc_pos(linebuf, curchar),
- X calc_pos(linebuf, strlen(linebuf)));
- X}
- X
- X#define IF_UNBOUND -1
- X#define IF_TRUE 1
- X#define IF_FALSE !IF_TRUE
- X
- X#ifndef MAC
- int
- do_if(cmd)
- char *cmd;
- X{
- X#ifdef MSDOS
- X int status;
- X#else
- X int pid,
- X status;
- X#endif /* MSDOS */
- X#ifndef MSDOS
- X
- X switch (pid = fork()) {
- X case -1:
- X complain("[Fork failed: if]");
- X
- X case 0:
- X {
- X#endif /* MSDOS */
- X char *args[12],
- X *cp = cmd,
- X **ap = args;
- X
- X *ap++ = cmd;
- X for (;;) {
- X if ((cp = index(cp, ' ')) == 0)
- X break;
- X *cp++ = '\0';
- X *ap++ = cp;
- X }
- X *ap = 0;
- X
- X#ifndef MSDOS
- X close(0); /* we want reads to fail */
- X /* close(1); but not writes or ioctl's
- X close(2); */
- X#else /* MSDOS */
- X if ((status = spawnvp(0, args[0], args)) < 0)
- X complain("[Spawn failed: if]");
- X#endif /* MSDOS */
- X
- X#ifndef MSDOS
- X (void) execvp(args[0], args);
- X _exit(-10); /* signals exec error (see below) */
- X }
- X }
- X#ifdef IPROCS
- X sighold(SIGCHLD);
- X#endif
- X dowait(pid, &status);
- X#ifdef IPROCS
- X sigrelse(SIGCHLD);
- X#endif
- X if (status == -10)
- X complain("[Exec failed]");
- X if (status < 0)
- X complain("[Exit %d]", status);
- X#endif /* MSDOS */
- X return (status == 0); /* 0 means successful */
- X}
- X#endif /* MAC */
- X
- int
- joverc(file)
- char *file;
- X{
- X char buf[LBSIZE],
- X lbuf[LBSIZE];
- X int lnum = 0,
- X eof = FALSE;
- X jmp_buf savejmp;
- X int IfStatus = IF_UNBOUND;
- X File *fp;
- X
- X fp = open_file(file, buf, F_READ, !COMPLAIN, QUIET);
- X if (fp == NIL)
- X return NO; /* joverc returns an integer */
- X
- X /* Catch any errors, here, and do the right thing with them,
- X and then restore the error handle to whoever did a setjmp
- X last. */
- X
- X InJoverc += 1;
- X push_env(savejmp);
- X if (setjmp(mainjmp)) {
- X Buffer *savebuf = curbuf;
- X
- X SetBuf(do_select((Window *) 0, "RC errors"));
- X ins_str(sprint("%s:%d:%s\t%s\n", pr_name(file, YES), lnum, lbuf, mesgbuf), NO);
- X unmodify();
- X SetBuf(savebuf);
- X Asking = 0;
- X }
- X if (!eof) do {
- X eof = (f_gets(fp, lbuf, sizeof lbuf) == EOF);
- X lnum += 1;
- X if (lbuf[0] == '#') /* a comment */
- X continue;
- X#ifndef MAC
- X if (casencmp(lbuf, "if", 2) == 0) {
- X char cmd[128];
- X
- X if (IfStatus != IF_UNBOUND)
- X complain("[Cannot have nested if's]");
- X if (LookingAt("if[ \t]*\\(.*\\)$", lbuf, 0) == 0)
- X complain("[If syntax error]");
- X putmatch(1, cmd, sizeof cmd);
- X IfStatus = do_if(cmd) ? IF_TRUE : IF_FALSE;
- X continue;
- X } else if (casencmp(lbuf, "else", 4) == 0) {
- X if (IfStatus == IF_UNBOUND)
- X complain("[Unexpected `else']");
- X IfStatus = !IfStatus;
- X continue;
- X } else if (casencmp(lbuf, "endif", 5) == 0) {
- X if (IfStatus == IF_UNBOUND)
- X complain("[Unexpected `endif']");
- X IfStatus = IF_UNBOUND;
- X continue;
- X }
- X#endif
- X if (IfStatus == IF_FALSE)
- X continue;
- X (void) strcat(lbuf, "\n");
- X Inputp = lbuf;
- X while (*Inputp == ' ' || *Inputp == '\t')
- X Inputp += 1; /* skip white space */
- X Extend();
- X } while (!eof);
- X
- X f_close(fp);
- X pop_env(savejmp);
- X Inputp = 0;
- X Asking = 0;
- X InJoverc -= 1;
- X if (IfStatus != IF_UNBOUND)
- X complain("[Missing endif]");
- X return 1;
- X}
- END_OF_FILE
- if test 19914 -ne `wc -c <'./extend.c'`; then
- echo shar: \"'./extend.c'\" unpacked with wrong size!
- fi
- # end of './extend.c'
- fi
- if test -f './re.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./re.c'\"
- else
- echo shar: Extracting \"'./re.c'\" \(18437 characters\)
- sed "s/^X//" >'./re.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X/* search package */
- X
- X#include "jove.h"
- X#include "ctype.h"
- X#ifdef MAC
- X# undef private
- X# define private
- X#endif
- X
- X#ifdef LINT_ARGS
- private char * insert(char *, char *, int);
- X
- private void
- X REreset(void),
- X search(int, int, int);
- private int
- X backref(int, char *),
- X do_comp(int),
- X member(char *, int, int),
- X REgetc(void),
- X REmatch(char *, char *);
- X#else
- private char * insert();
- X
- private void
- X REreset(),
- X search();
- private int
- X backref(),
- X do_comp(),
- X member(),
- X REgetc(),
- X REmatch();
- X#endif /* LINT_ARGS */
- X
- X#ifdef MAC
- X# undef private
- X# define private static
- X#endif
- X
- X#define NALTS 16 /* number of alternate search strings */
- X
- char searchstr[128],
- X compbuf[256], /* global default compbuf */
- X rep_search[128], /* replace search string */
- X rep_str[128], /* contains replacement string */
- X *cur_compb, /* usually points at compbuf */
- X REbuf[LBSIZE], /* points at line we're scanning */
- X *alternates[NALTS];
- X
- int REdirection;
- X
- int CaseIgnore = 0,
- X WrapScan = 0,
- X UseRE = 0;
- X
- X#define cind_cmp(a, b) (CaseEquiv[a] == CaseEquiv[b])
- X
- private int REpeekc;
- private char *REptr;
- X
- private int
- REgetc()
- X{
- X int c;
- X
- X if ((c = REpeekc) != -1)
- X REpeekc = -1;
- X else if (*REptr)
- X c = *REptr++;
- X else
- X c = 0;
- X
- X return c;
- X}
- X
- X#define STAR 01 /* Match any number of last RE. */
- X#define AT_BOL 2 /* ^ */
- X#define AT_EOL 4 /* $ */
- X#define AT_BOW 6 /* \< */
- X#define AT_EOW 8 /* \> */
- X#define OPENP 10 /* \( */
- X#define CLOSEP 12 /* \) */
- X#define CURLYB 14 /* \{ */
- X
- X#define NOSTR 14 /* Codes <= NOSTR can't be *'d. */
- X
- X#define ANYC NOSTR+2 /* . */
- X#define NORMC ANYC+2 /* normal character */
- X#define CINDC NORMC+2 /* case independent character */
- X#define ONE_OF CINDC+2 /* [xxx] */
- X#define NONE_OF ONE_OF+2 /* [^xxx] */
- X#define BACKREF NONE_OF+2 /* \# */
- X#define EOP BACKREF+2 /* end of pattern */
- X
- X#define NPAR 10 /* [0-9] - 0th is the entire matched string, i.e. & */
- private int nparens;
- private char *comp_p,
- X *start_p,
- X **alt_p,
- X **alt_endp;
- X
- void
- REcompile(pattern, re, into_buf, alt_bufp)
- char *pattern,
- X *into_buf,
- X **alt_bufp;
- X{
- X REptr = pattern;
- X REpeekc = -1;
- X comp_p = cur_compb = start_p = into_buf;
- X alt_p = alt_bufp;
- X alt_endp = alt_p + NALTS;
- X *alt_p++ = comp_p;
- X nparens = 0;
- X (void) do_comp(re ? OKAY_RE : NORM);
- X *alt_p = 0;
- X}
- X
- X/* compile the pattern into an internal code */
- X
- private int
- do_comp(kind)
- X{
- X char *last_p,
- X *chr_cnt = 0;
- X int parens[NPAR],
- X *parenp,
- X c,
- X ret_code;
- X
- X parenp = parens;
- X last_p = 0;
- X ret_code = 1;
- X
- X if (kind == OKAY_RE) {
- X *comp_p++ = OPENP;
- X *comp_p++ = nparens;
- X *parenp++ = nparens++;
- X start_p = comp_p;
- X }
- X
- X while (c = REgetc()) {
- X if (comp_p > &cur_compb[(sizeof compbuf) - 6])
- toolong: complain("Search string too long/complex.");
- X if (c != '*')
- X last_p = comp_p;
- X
- X if (kind == NORM && index(".[*", c) != 0)
- X goto defchar;
- X switch (c) {
- X case '\\':
- X switch (c = REgetc()) {
- X case 0:
- X complain("Premature end of pattern.");
- X
- X case '{':
- X {
- X char *wcntp; /* word count */
- X
- X *comp_p++ = CURLYB;
- X wcntp = comp_p;
- X *comp_p++ = 0;
- X for (;;) {
- X int comp_val;
- X char *comp_len;
- X
- X comp_len = comp_p++;
- X comp_val = do_comp(IN_CB);
- X *comp_len = comp_p - comp_len;
- X (*wcntp) += 1;
- X if (comp_val == 0)
- X break;
- X }
- X break;
- X }
- X
- X case '}':
- X if (kind != IN_CB)
- X complain("Unexpected \}.");
- X ret_code = 0;
- X goto outahere;
- X
- X case '(':
- X if (nparens >= NPAR)
- X complain("Too many ('s; max is %d.", NPAR);
- X *comp_p++ = OPENP;
- X *comp_p++ = nparens;
- X *parenp++ = nparens++;
- X break;
- X
- X case ')':
- X if (parenp == parens)
- X complain("Too many )'s.");
- X *comp_p++ = CLOSEP;
- X *comp_p++ = *--parenp;
- X break;
- X
- X case '|':
- X if (alt_p >= alt_endp)
- X complain("Too many alternates; max %d.", NALTS);
- X *comp_p++ = CLOSEP;
- X *comp_p++ = *--parenp;
- X *comp_p++ = EOP;
- X *alt_p++ = comp_p;
- X nparens = 0;
- X *comp_p++ = OPENP;
- X *comp_p++ = nparens;
- X *parenp++ = nparens++;
- X start_p = comp_p;
- X break;
- X
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X *comp_p++ = BACKREF;
- X *comp_p++ = c - '0';
- X break;
- X
- X case '<':
- X *comp_p++ = AT_BOW;
- X break;
- X
- X case '>':
- X *comp_p++ = AT_EOW;
- X break;
- X
- X default:
- X goto defchar;
- X }
- X break;
- X
- X case ',':
- X if (kind != IN_CB)
- X goto defchar;
- X goto outahere;
- X
- X case '.':
- X *comp_p++ = ANYC;
- X break;
- X
- X case '^':
- X if (comp_p == start_p) {
- X *comp_p++ = AT_BOL;
- X break;
- X }
- X goto defchar;
- X
- X case '$':
- X if ((REpeekc = REgetc()) != 0 && REpeekc != '\\')
- X goto defchar;
- X *comp_p++ = AT_EOL;
- X break;
- X
- X case '[':
- X {
- X int chrcnt;
- X
- X *comp_p++ = ONE_OF;
- X if (comp_p + 16 >= &cur_compb[(sizeof compbuf)])
- X goto toolong;
- X bzero(comp_p, 16);
- X if ((REpeekc = REgetc()) == '^') {
- X *last_p = NONE_OF;
- X /* Get it for real this time. */
- X (void) REgetc();
- X }
- X chrcnt = 1;
- X while ((c = REgetc()) != ']' && c != 0) {
- X if (c == '\\')
- X c = REgetc();
- X else if ((REpeekc = REgetc()) == '-') {
- X int c2;
- X
- X (void) REgetc(); /* reread '-' */
- X c2 = REgetc();
- X while (c < c2) {
- X comp_p[c/8] |= (1 << (c%8));
- X c += 1;
- X }
- X }
- X comp_p[c/8] |= (1 << (c%8));
- X chrcnt += 1;
- X }
- X if (c == 0)
- X complain("Missing ].");
- X if (chrcnt == 1)
- X complain("Empty [].");
- X comp_p += 16;
- X break;
- X }
- X
- X case '*':
- X if (last_p == 0 || *last_p <= NOSTR)
- X goto defchar;
- X
- X /* The * operator applies only to the previous
- X character. If we were building a chr_cnt at
- X the time we got the *, we have to remove the
- X last character from the chr_cnt (by decrementing
- X *chr_cnt) and replacing it with a new STAR entry.
- X
- X If we are decrementing the count to 0, we just
- X delete the chr_cnt entry altogether, replacing
- X it with the STAR entry. */
- X
- X if (chr_cnt) {
- X char lastc = chr_cnt[*chr_cnt];
- X
- X /* The * operator applies only to the previous
- X character. If we were building a chr_cnt at
- X the time we got the *, we have to remove the
- X last character from the chr_cnt (by decrementing
- X *chr_cnt) and replacing it with a new STAR entry.
- X
- X If we are decrementing the count to 0, we just
- X delete the chr_cnt entry altogether, replacing
- X it with the STAR entry. */
- X
- X if (*chr_cnt == 1) {
- X comp_p = chr_cnt;
- X comp_p[-1] |= STAR;
- X *comp_p++ = lastc;
- X } else {
- X comp_p = chr_cnt + *chr_cnt;
- X (*chr_cnt) -= 1;
- X *comp_p++ = chr_cnt[-1] | STAR;
- X *comp_p++ = lastc;
- X }
- X } else
- X *last_p |= STAR;
- X break;
- X default:
- defchar: if (chr_cnt)
- X (*chr_cnt) += 1;
- X else {
- X *comp_p++ = (CaseIgnore) ? CINDC : NORMC;
- X chr_cnt = comp_p++;
- X *chr_cnt = 1; /* last_p[1] = 1; */
- X }
- X *comp_p++ = c;
- X continue;
- X }
- X chr_cnt = FALSE;
- X }
- outahere:
- X /* End of pattern, let's do some error checking. */
- X if (kind == OKAY_RE) {
- X *comp_p++ = CLOSEP;
- X *comp_p++ = *--parenp;
- X }
- X if (parenp != parens)
- X complain("Unmatched ()'s.");
- X if (kind == IN_CB && c == 0) /* End of pattern with \}. */
- X complain("Missing \}.");
- X *comp_p++ = EOP;
- X
- X return ret_code;
- X}
- X
- private char *pstrtlst[NPAR], /* index into REbuf */
- X *pendlst[NPAR],
- X *REbolp,
- X *locs,
- X *loc1,
- X *loc2;
- X
- int REbom,
- X REeom, /* beginning and end of match */
- X REalt_num; /* if alternatives, which one matched? */
- X
- private int
- backref(n, linep)
- register char *linep;
- X{
- X register char *backsp,
- X *backep;
- X
- X backsp = pstrtlst[n];
- X backep = pendlst[n];
- X while (*backsp++ == *linep++)
- X if (backsp >= backep)
- X return 1;
- X return 0;
- X}
- X
- private int
- member(comp_p, c, af)
- register char *comp_p;
- register int c,
- X af;
- X{
- X if (c == 0)
- X return 0; /* try to match EOL always fails */
- X if (comp_p[c/8] & (1 << (c%8)))
- X return af;
- X return !af;
- X}
- X
- private int
- REmatch(linep, comp_p)
- register char *linep,
- X *comp_p;
- X{
- X char *first_p = linep;
- X register int n;
- X
- X for (;;) switch (*comp_p++) {
- X case NORMC:
- X n = *comp_p++;
- X while (--n >= 0)
- X if (*linep++ != *comp_p++)
- X return 0;
- X continue;
- X
- X case CINDC: /* case independent comparison */
- X n = *comp_p++;
- X while (--n >= 0)
- X if (!cind_cmp(*linep++, *comp_p++))
- X return 0;
- X continue;
- X
- X case EOP:
- X loc2 = linep;
- X REeom = (loc2 - REbolp);
- X return 1; /* Success! */
- X
- X case AT_BOL:
- X if (linep == REbolp)
- X continue;
- X return 0;
- X
- X case AT_EOL:
- X if (*linep == 0)
- X continue;
- X return 0;
- X
- X case ANYC:
- X if (*linep++ != 0)
- X continue;
- X return 0;
- X
- X case AT_BOW:
- X if (ismword(*linep) && (linep == REbolp || !ismword(linep[-1])))
- X continue;
- X return 0;
- X
- X case AT_EOW:
- X if ((*linep == 0 || !ismword(*linep)) &&
- X (linep != REbolp && ismword(linep[-1])))
- X continue;
- X return 0;
- X
- X case ONE_OF:
- X case NONE_OF:
- X if (member(comp_p, *linep++, comp_p[-1] == ONE_OF)) {
- X comp_p += 16;
- X continue;
- X }
- X return 0;
- X
- X case OPENP:
- X pstrtlst[*comp_p++] = linep;
- X continue;
- X
- X case CLOSEP:
- X pendlst[*comp_p++] = linep;
- X continue;
- X
- X case BACKREF:
- X if (pstrtlst[n = *comp_p++] == 0) {
- X s_mess("\\%d was not specified.", n + 1);
- X return 0;
- X }
- X if (backref(n, linep)) {
- X linep += pendlst[n] - pstrtlst[n];
- X continue;
- X }
- X return 0;
- X
- X case CURLYB:
- X {
- X int wcnt,
- X any;
- X
- X wcnt = *comp_p++;
- X any = 0;
- X
- X while (--wcnt >= 0) {
- X if (any == 0)
- X any = REmatch(linep, comp_p + 1);
- X comp_p += *comp_p;
- X }
- X if (any == 0)
- X return 0;
- X linep = loc2;
- X continue;
- X }
- X
- X case ANYC | STAR:
- X first_p = linep;
- X while (*linep++)
- X ;
- X goto star;
- X
- X case NORMC | STAR:
- X first_p = linep;
- X while (*comp_p == *linep++)
- X ;
- X comp_p += 1;
- X goto star;
- X
- X case CINDC | STAR:
- X first_p = linep;
- X while (cind_cmp(*comp_p, *linep++))
- X ;
- X comp_p += 1;
- X goto star;
- X
- X case ONE_OF | STAR:
- X case NONE_OF | STAR:
- X first_p = linep;
- X while (member(comp_p, *linep++, comp_p[-1] == (ONE_OF | STAR)))
- X ;
- X comp_p += 16;
- X goto star;
- X
- X case BACKREF | STAR:
- X first_p = linep;
- X n = *comp_p++;
- X while (backref(n, linep))
- X linep += pendlst[n] - pstrtlst[n];
- X while (linep >= first_p) {
- X if (REmatch(linep, comp_p))
- X return 1;
- X linep -= pendlst[n] - pstrtlst[n];
- X }
- X continue;
- X
- star: do {
- X linep -= 1;
- X if (linep < locs)
- X break;
- X if (REmatch(linep, comp_p))
- X return 1;
- X } while (linep > first_p);
- X return 0;
- X
- X default:
- X complain("RE error match (%d).", comp_p[-1]);
- X }
- X /* NOTREACHED. */
- X}
- X
- private void
- REreset()
- X{
- X register int i;
- X
- X for (i = 0; i < NPAR; i++)
- X pstrtlst[i] = pendlst[i] = 0;
- X}
- X
- X/* Index LINE at OFFSET, the compiled EXPR, with alternates ALTS. If
- X lbuf_okay is nonzero it's okay to use linebuf if LINE is the current
- X line. This should save lots of time in things like paren matching in
- X LISP mode. Saves all that copying from linebuf to REbuf. substitute()
- X is the guy who calls re_lindex with lbuf_okay as 0, since the substitution
- X gets placed in linebuf ... doesn't work too well when the source and
- X destination strings are the same. I hate all these arguments!
- X
- X This code is cumbersome, repetetive for reasons of efficiency. Fast
- X search is a must as far as I am concerned. */
- X
- int
- re_lindex(line, offset, expr, alts, lbuf_okay)
- Line *line;
- char *expr,
- X **alts;
- X{
- X int isquick;
- X register int firstc,
- X c;
- X register char *resp;
- X
- X REreset();
- X if (lbuf_okay) {
- X REbolp = lbptr(line);
- X if (offset == -1)
- X offset = strlen(REbolp); /* arg! */
- X } else {
- X REbolp = ltobuf(line, REbuf);
- X if (offset == -1) { /* Reverse search, find end of line. */
- X extern int Jr_Len;
- X
- X offset = Jr_Len; /* Just Read Len. */
- X }
- X }
- X resp = REbolp;
- X isquick = ((expr[0] == NORMC || expr[0] == CINDC) &&
- X (alternates[1] == 0));
- X if (isquick) {
- X firstc = expr[2];
- X if (expr[0] == CINDC)
- X firstc = CaseEquiv[firstc];
- X }
- X locs = REbolp + offset;
- X
- X if (REdirection == FORWARD) {
- X do {
- X char **altp = alts;
- X
- X if (isquick) {
- X if (expr[0] == NORMC)
- X while ((c = *locs++) != 0 && c != firstc)
- X ;
- X else
- X while (((c = *locs++) != 0) &&
- X (CaseEquiv[c] != firstc))
- X ;
- X if (*--locs == 0)
- X break;
- X }
- X REalt_num = 1;
- X while (*altp) {
- X if (REmatch(locs, *altp++)) {
- X loc1 = locs;
- X REbom = loc1 - REbolp;
- X return 1;
- X }
- X REalt_num += 1;
- X }
- X } while (*locs++);
- X } else {
- X do {
- X char **altp = alts;
- X
- X if (isquick) {
- X if (expr[0] == NORMC) {
- X while (locs >= REbolp && *locs-- != firstc)
- X ;
- X if (*++locs != firstc)
- X break;
- X } else {
- X while (locs >= REbolp && CaseEquiv[*locs--] != firstc)
- X ;
- X if (CaseEquiv[*++locs] != firstc)
- X break;
- X }
- X }
- X REalt_num = 1;
- X while (*altp) {
- X if (REmatch(locs, *altp++)) {
- X loc1 = locs;
- X REbom = loc1 - REbolp;
- X return 1;
- X }
- X REalt_num += 1;
- X }
- X } while (--locs >= resp);
- X }
- X
- X return 0;
- X}
- X
- int okay_wrap = 0; /* Do a wrap search ... not when we're
- X parsing errors ... */
- X
- Bufpos *
- dosearch(pattern, dir, re)
- char *pattern;
- X{
- X Bufpos *pos;
- X
- X if (bobp() && eobp()) /* Can't match! There's no buffer. */
- X return 0;
- X
- X REcompile(pattern, re, compbuf, alternates);
- X
- X pos = docompiled(dir, compbuf, alternates);
- X return pos;
- X}
- X
- Bufpos *
- docompiled(dir, expr, alts)
- char *expr,
- X **alts;
- X{
- X static Bufpos ret;
- X register Line *lp;
- X register int offset;
- X int we_wrapped = NO;
- X
- X lsave();
- X /* Search now lsave()'s so it doesn't make any assumptions on
- X whether the the contents of curline/curchar are in linebuf.
- X Nowhere does search write all over linebuf. However, we have to
- X be careful about what calls we make here, because many of them
- X assume (and rightly so) that curline is in linebuf. */
- X
- X REdirection = dir;
- X lp = curline;
- X offset = curchar;
- X if (dir == BACKWARD) {
- X if (bobp()) {
- X if (okay_wrap && WrapScan)
- X goto doit;
- X return 0;
- X }
- X /* here we simulate BackChar() */
- X if (bolp()) {
- X lp = lp->l_prev;
- X offset = strlen(lbptr(lp));
- X } else
- X offset -= 1;
- X } else if ((dir == FORWARD) &&
- X (lbptr(lp)[offset] == '\0') &&
- X !lastp(lp)) {
- X lp = lp->l_next;
- X offset = 0;
- X }
- X
- X do {
- X if (re_lindex(lp, offset, expr, alts, YES))
- X break;
- doit: lp = (dir == FORWARD) ? lp->l_next : lp->l_prev;
- X if (lp == 0) {
- X if (okay_wrap && WrapScan) {
- X lp = (dir == FORWARD) ?
- X curbuf->b_first : curbuf->b_last;
- X we_wrapped = YES;
- X } else
- X break;
- X }
- X if (dir == FORWARD)
- X offset = 0;
- X else
- X offset = -1; /* signals re_lindex ... */
- X } while (lp != curline);
- X
- X if (lp == curline && we_wrapped)
- X lp = 0;
- X if (lp == 0)
- X return 0;
- X ret.p_line = lp;
- X ret.p_char = (dir == FORWARD) ? REeom : REbom;
- X return &ret;
- X}
- X
- private char *
- insert(off, endp, which)
- char *off,
- X *endp;
- X{
- X register char *pp;
- X register int n;
- X
- X n = pendlst[which] - pstrtlst[which];
- X pp = pstrtlst[which];
- X while (--n >= 0) {
- X *off++ = *pp++;
- X if (off >= endp)
- X len_error(ERROR);
- X }
- X return off;
- X}
- X
- X/* Perform the substitution. If DELP is nonzero the matched string is
- X deleted, i.e., the substitution string is not inserted. */
- X
- void
- re_dosub(tobuf, delp)
- char *tobuf;
- X{
- X register char *tp,
- X *rp,
- X *repp;
- X int c;
- X char *endp;
- X
- X tp = tobuf;
- X endp = tp + LBSIZE;
- X rp = REbuf;
- X repp = rep_str;
- X
- X while (rp < loc1)
- X *tp++ = *rp++;
- X
- X if (!delp) while (c = *repp++) {
- X if (c == '\\') {
- X c = *repp++;
- X if (c == '\0') {
- X *tp++ = '\\';
- X goto endchk;
- X } else if (c >= '1' && c <= nparens + '1') {
- X tp = insert(tp, endp, c - '0');
- X continue;
- X }
- X } else if (c == '&') {
- X tp = insert(tp, endp, 0);
- X continue;
- X }
- X *tp++ = c;
- endchk: if (tp >= endp)
- X len_error(ERROR);
- X }
- X rp = loc2;
- X loc2 = REbuf + max(1, tp - tobuf);
- X REeom = loc2 - REbuf;
- X /* At least one character past the match, to prevent an infinite
- X number of replacements in the same position, e.g.,
- X replace "^" with "". */
- X while (*tp++ = *rp++)
- X if (tp >= endp)
- X len_error(ERROR);
- X}
- X
- void
- putmatch(which, buf, size)
- char *buf;
- X{
- X *(insert(buf, buf + size, which)) = 0;
- X}
- X
- void
- setsearch(str)
- char *str;
- X{
- X strcpy(searchstr, str);
- X}
- X
- char *
- getsearch()
- X{
- X return searchstr;
- X}
- X
- void
- RErecur()
- X{
- X char sbuf[sizeof searchstr],
- X cbuf[sizeof compbuf],
- X repbuf[sizeof rep_str],
- X *altbuf[NALTS];
- X int npars;
- X Mark *m = MakeMark(curline, REbom, M_FLOATER);
- X
- X message("Type C-X C-C to continue with query replace.");
- X
- X npars = nparens;
- X byte_copy(compbuf, cbuf, sizeof compbuf);
- X byte_copy(searchstr, sbuf, sizeof searchstr);
- X byte_copy(rep_str, repbuf, sizeof rep_str);
- X byte_copy((char *) alternates, (char *) altbuf, sizeof alternates);
- X Recur();
- X nparens = npars;
- X byte_copy(cbuf, compbuf, sizeof compbuf);
- X byte_copy(sbuf, searchstr, sizeof searchstr);
- X byte_copy(repbuf, rep_str, sizeof rep_str);
- X byte_copy((char *) altbuf, (char *) alternates, sizeof alternates);
- X if (!is_an_arg())
- X ToMark(m);
- X DelMark(m);
- X}
- X
- void
- ForSearch()
- X{
- X search(FORWARD, UseRE, YES);
- X}
- X
- void
- RevSearch()
- X{
- X search(BACKWARD, UseRE, YES);
- X}
- X
- void
- FSrchND()
- X{
- X search(FORWARD, UseRE, NO);
- X}
- X
- void
- RSrchND()
- X{
- X search(BACKWARD, UseRE, NO);
- X}
- X
- private void
- search(dir, re, setdefault)
- X{
- X Bufpos *newdot;
- X char *s;
- X
- X s = ask(searchstr, ProcFmt);
- X if (setdefault)
- X setsearch(s);
- X okay_wrap = YES;
- X newdot = dosearch(s, dir, re);
- X okay_wrap = NO;
- X if (newdot == 0) {
- X if (WrapScan)
- X complain("No \"%s\" in buffer.", s);
- X else
- X complain("No \"%s\" found to %s.", s,
- X (dir == FORWARD) ? "bottom" : "top");
- X }
- X PushPntp(newdot->p_line);
- X SetDot(newdot);
- X}
- X
- X/* Do we match PATTERN at OFFSET in BUF? */
- X
- int
- LookingAt(pattern, buf, offset)
- char *pattern,
- X *buf;
- X{
- X register char **alt = alternates;
- X
- X REcompile(pattern, 1, compbuf, alternates);
- X REreset();
- X locs = buf + offset;
- X REbolp = buf;
- X
- X while (*alt)
- X if (REmatch(locs, *alt++))
- X return 1;
- X return 0;
- X}
- X
- int
- look_at(expr)
- char *expr;
- X{
- X REcompile(expr, 0, compbuf, alternates);
- X REreset();
- X locs = linebuf + curchar;
- X REbolp = linebuf;
- X if (REmatch(locs, alternates[0]))
- X return 1;
- X return 0;
- X}
- X
- END_OF_FILE
- if test 18437 -ne `wc -c <'./re.c'`; then
- echo shar: \"'./re.c'\" unpacked with wrong size!
- fi
- # end of './re.c'
- fi
- echo shar: End of archive 10 \(of 21\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-